package work.huangxin.share.controller.wx;

import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import work.huangxin.share.constant.WxConstant;
import work.huangxin.share.domain.wx.ChatGptResponse;
import work.huangxin.share.domain.wx.ReceiveMessage;
import work.huangxin.share.domain.wx.Text;
import work.huangxin.share.domain.wx.WxCustomMessage;
import work.huangxin.share.service.WechatService;
import work.huangxin.share.util.XMLUtil;
import work.huangxin.share.util.common.JsonUtils;
import work.huangxin.share.util.status.BaseResponse;
import work.huangxin.share.util.status.ResponseData;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import static cn.hutool.crypto.SecureUtil.sha1;


/**
 * @author: 张锦标
 * @date: 2023/4/2 10:09
 * WechatController
 */
@RestController
@RequestMapping("/wx")
public class WechatController {

    @Autowired
    private WechatService wechatService;
    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;
    @Value("${wechat.mp.token}")
    private String token;

    @Value("${wechat.mp.appId}")
    private String appId;
    @Value("${wechat.mp.secret}")
    private String secret;
    Logger log = LoggerFactory.getLogger(WechatController.class);


    @GetMapping("/chat")
    public String checkToken(HttpServletRequest request){
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");
        //将除了签名外的参数进行排序
        String[] sign = {timestamp,nonce,token};
        Arrays.sort(sign);
        //进行加密后，与signature进行比较
        String afterSign = sha1(sign[0] + sign[1] + sign[2]);
        if (afterSign.equals(signature)){
            return echostr;
        }
        return "";
    }
    @GetMapping("/getToken")
    public BaseResponse getToken(){
        String accessToken = wechatService.getAccessToken(appId, secret);
        return ResponseData.success(accessToken);
    }
    @PostMapping("/chat")
    public String testResponse( HttpServletResponse response,
                              HttpServletRequest request,
                              @RequestBody String requestBody, @RequestParam("signature") String signature,
                              @RequestParam("timestamp") String timestamp, @RequestParam("nonce") String nonce,
                              @RequestParam(name = "encrypt_type", required = false) String encType,
                              @RequestParam(name = "msg_signature", required = false) String msgSignature){
        System.out.println("requestbody:----"+requestBody);
        ReceiveMessage receiveMessage = XMLUtil.XMLTOModel(requestBody);
        System.out.println("receiceMessgae=====>"+receiveMessage.toString());
        threadPoolExecutor.execute(() -> {
            //异步调用客服接口，只需要在48小时内给出响应即可
            //得到用户的OpenId
            getCustomResponse(receiveMessage.getFromUserName(),receiveMessage.getContent());
        });
        return parseMsgToXML(receiveMessage);
    }


    /**
     * 调用客服接口
     * @param openId
     * @param content
     * @return
     */

    @GetMapping("/customResponse")
    public BaseResponse getCustomResponse(String openId,String content){
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(300, TimeUnit.SECONDS)
                .writeTimeout(100, TimeUnit.SECONDS)
                .readTimeout(100, TimeUnit.SECONDS)
                .callTimeout(100, TimeUnit.SECONDS)
                .build();
        //替换url中的token,远程调用微信的接口得到accessToken
        String url = WxConstant.Send_Custom_Message.replace("ACCESS_TOKEN", wechatService.getAccessToken(appId, secret));;
        /**
         * 设置返回类型为json
         */
        MediaType mediaType = MediaType.parse("application/json");
        WxCustomMessage wxCustomMessage = new WxCustomMessage();
        //得到openId
        wxCustomMessage.setTouser(openId);
        wxCustomMessage.setMsgtype("text");
        Text text = new Text();
            text.setContent(wechatService.getContentFromGpt(content));
        wxCustomMessage.setText(text);
        //将请求体设置为JSON
        String requestBody = JsonUtils.objectToJson(wxCustomMessage);
        //构建请求
        Request request = new Request.Builder()
                .url(url)
                .post(okhttp3.RequestBody.create(mediaType, requestBody))
                .build();
        //发起请求
        Response response = null;
        try {
            response = okHttpClient.newCall(request).execute();
            if (response.isSuccessful()){
                log.info("POST请求得到的响应体: response======>"+response.body().string());
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return ResponseData.success();
    }


    /**
     * 生成回答问题的xml
     * @param receiveMessage
     * @return
     */

    private String parseMsgToXML(ReceiveMessage receiveMessage) {
            // 创建document对象
            Document document = DocumentHelper.createDocument();
            // 创建根节点bookRoot
            Element xml = document.addElement("xml");
            // 向根节点中添加第一个节点
            Element toUserName = xml.addElement("ToUserName");
            // 向子节点中添加属性
            toUserName.addCDATA(receiveMessage.getFromUserName());
            Element fromUserName = xml.addElement("FromUserName");
            fromUserName.addCDATA(receiveMessage.getToUserName());
            Element createTime = xml.addElement("CreateTime");
            createTime.addCDATA(String.valueOf(System.currentTimeMillis()));
            Element msgType = xml.addElement("MsgType");
            msgType.addCDATA(receiveMessage.getMsgType());
            Element content = xml.addElement("Content");
            content.addCDATA("请耐心等待AI生成回答...");
            //将文档对象转化为xml字符串
            String asXML = document.getRootElement().asXML();
            System.out.println(asXML);
            return asXML;
    }
    @PostMapping("/testGPTResponse")
    public BaseResponse testGPTResponse(@RequestBody ChatGptResponse chatGptResponse){
        return ResponseData.success(chatGptResponse);
    }


}